package handler

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"gitee.com/ddlin/kit/xlog"
	"gitee.com/ddlin/tiktok-go-tool/service"
	"github.com/gin-gonic/gin"
	"github.com/tencentyun/cos-go-sdk-v5"
)

type ToolSrv struct {
	response    *Response
	httpService *service.HttpService
	cosClient   *cos.Client
}

func NewToolSrv(
	response *Response,
	httpService *service.HttpService,
	cosClient *cos.Client,
) *ToolSrv {
	return &ToolSrv{
		response:    response,
		httpService: httpService,
		cosClient:   cosClient,
	}
}

var (
	DoRequestMethodPostJson                = "post_json"
	DoRequestMethodGetJson                 = "get_json"
	DoRequestMethodGet                     = "get"
	DoRequestMethodGetParams               = "get_params"
	DORequestMethodPostMultipart           = "post_multipart"
	DORequestMethodPostMultipartByFilename = "post_multipart_filename"
)

type DoRequestParam struct {
	Url          string            `json:"url"`
	Header       map[string]string `json:"header"`
	Body         string            `json:"body"`
	Method       string            `json:"method"`
	AdvertiserId string            `json:"advertiser_id"`
	FileItem     *service.FileItem `json:"file_item"`
	BodyMap      map[string]string `json:"body_map"`
	GetParams    map[string]string `json:"get_params"`
	IsConversion bool              `json:"is_conversion"` // 是否回传， 回传不需要限制器
	Filename     string            `json:"filename"`
}

// UsDoRequest us转发
func (ins *ToolSrv) UsDoRequest(ctx context.Context, params DoRequestParam) ([]byte, error) {

	var retBytes []byte
	var err error

	switch params.Method {
	case DoRequestMethodPostJson:
		retBytes, err = ins.httpService.Post(ctx, "long", params.Url, params.Header, params.Body)
	case DoRequestMethodGet:
		retBytes, err = ins.httpService.Get(ctx, "long", params.Url, params.Header)
	case DoRequestMethodGetJson:
		retBytes, err = ins.httpService.GetWithJson(ctx, "long", params.Url, params.Header, params.Body)
	case DORequestMethodPostMultipart:
		retBytes, err = ins.httpService.PostWithMultipart(ctx, "long", params.Url, params.Header, params.BodyMap, params.FileItem)
	case DoRequestMethodGetParams:
		retBytes, err = ins.httpService.GetWithParams(ctx, "long", params.Url, params.Header, params.GetParams)
	case DORequestMethodPostMultipartByFilename:
		// 从bucket拉取文件
		objectRes, err := ins.cosClient.Object.Get(ctx, params.Filename, nil, "")
		if err != nil {
			return nil, err
		}

		defer objectRes.Body.Close()

		fileData, _ := io.ReadAll(objectRes.Body)

		fileItem := service.FileItem{
			FileName: params.Filename,
			Key:      "file",
			Content:  fileData,
		}

		retBytes, err = ins.httpService.PostWithMultipart(ctx, "long", params.Url, params.Header, params.BodyMap, &fileItem)
		if err != nil {
			xlog.S(ctx).Errorf("do request error: %+v", err)
			return nil, err
		}

	default:
		return nil, fmt.Errorf("unknown req method: %+v", params)
	}
	if err != nil {
		xlog.S(ctx).Errorf("do request error: %+v", err)
		return nil, err
	}

	return retBytes, nil
}

func (ins *ToolSrv) UsTransformTkApi(c *gin.Context) {
	ctx := c.Request.Context()
	var requestBody struct {
		DoRequestJson string `json:"do_request_json"`
	}

	if err := c.BindJSON(&requestBody); err != nil {
		ins.response.Error(c, err)
		return
	}

	if requestBody.DoRequestJson == "" {
		ins.response.Error(c, errors.New("参数错误"))
		return
	}

	var params DoRequestParam
	err := json.Unmarshal([]byte(requestBody.DoRequestJson), &params)
	if err != nil {
		xlog.S(ctx).Errorf("UsTransformApi err:%+v", err)
		ins.response.Error(c, err)
		return
	}

	xlog.S(ctx).Infof("UsTransformApi params:%+v", params)

	resp, err := ins.UsDoRequest(ctx, params)
	if err != nil {
		xlog.S(ctx).Errorf("UsDoRequest err:%+v", err)
		ins.response.Error(c, err)
		return
	}

	ins.response.Success(c, string(resp))
}
